<template>
  <div
    class="fa-widget-check-group"
    :class="[
      'fa-widget',
      data.className,
      `widget-mode-${data.mode}`,
      `actor-${data.actorColor}`,
      {
        'is-radio': isRadio,
        'is-addable': addButton.visible,
        'is-activate': widgetBase && widgetBase.active
      }
    ]"
    @mouseenter="hovering = true"
    @mouseleave="hovering = false"
  >
    <WidgetBase
      ref="widgetBase"
      class="select-box"
      :data="data"
      :parent="baseDrag.parent"
      @drop.native.stop
      @drag-start="baseDrag.dragStart"
      @dragging="baseDrag.dragging"
      @drag-stop="baseDrag.dragStop"
    >
      <ElTooltip
        v-if="addButton.visible"
        :content="addButton.disabledTips"
        :disabled="!addButton.disabledTips"
        @mousedown.stop
      >
        <a
          class="add-button el-icon-plus"
          :class="{ 'is-disabled': !!addButton.disabledTips }"
          @click="add()"
          @mousedown.stop
        ></a>
      </ElTooltip>
    </WidgetBase>

    <WidgetCheckOption
      v-for="(item, index) in data.checkOptions"
      :key="item.key"
      :data="data"
      :option="item"
      :active="activeIndex === index"
      :is-radio="isRadio"
      :is-readonly="isReadonly"
      :removable="removable"
      @mousedown.left.native.stop="activeOption(index)"
      @change="select"
      @remove="remove(index)"
    />
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, inject, nextTick, ref, toRef, toRefs, watch } from 'vue'
import { Viewer } from '@/types'
import { Widget } from '@/models'
import { EffectLock, awaitTimeout } from '@/utils'
import WidgetBase from '@/components/widget-base/WidgetBase.vue'
import useCheckGroup from './useCheckGroup'
import useBaseDrag from './useBaseDrag'
import WidgetCheckOption from './WidgetCheckOption.vue'

/** 单、复选框 */
export default defineComponent({
  name: 'FaWidgetCheckGroup',

  components: { WidgetBase, WidgetCheckOption },

  props: {
    /** 控件数据 */
    data: {
      type: Widget,
      required: true
    }
  },

  setup(props) {
    const viewer = inject('Viewer') as Viewer

    const widgetBase = ref(null as null | InstanceType<typeof WidgetBase>)

    const data = toRef(props, 'data')

    const refs = toRefs(useCheckGroup(data))

    const { options, box, activeIndex } = refs

    /** 控件移动 */
    const baseDrag = useBaseDrag(data, viewer)

    /** 激活锁 */
    const activeLocker = new EffectLock()

    /** 激活时锁定 */
    watch(
      () => viewer.activeWidgetId === props.data.id,
      active => active && activeLocker.lock()
    )

    /** 激活选项 */
    async function activeOption(index: number) {
      if (props.data.isSet) {
        activeIndex.value = index

        // 刚激活控件时，避免控件设置面板有动画导致滚动到选项失败，添加延时
        if (activeLocker.locked) {
          await awaitTimeout(400)
        } else {
          await nextTick()
        }

        const active = document.querySelector('.fa-widget-setting__option-list .is-option-active')

        if (active) {
          // 滚动到选项
          active.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
        }
      }
    }

    /** 鼠标悬浮 */
    const hovering = ref(false)

    /** 更新盒子 hover 状态 */
    watch(hovering, val => {
      const base = widgetBase.value
      if (base) {
        base.hovering = val
      }
    })

    /** 同步更新盒子尺寸和定位 */
    watch(box, data => Object.assign(props.data, data), { deep: true, immediate: true })

    /** 失去焦点 */
    watch(
      () => widgetBase.value?.active,
      active => {
        if (!active) activeIndex.value = -1
      }
    )

    /** 多选值 */
    const value = computed(() => JSON.stringify(options.value.map(item => item.value)))

    /** 更新控件值 */
    watch(value, val => (data.value.value = val), { immediate: true })

    /** 选项数量更改后，更新控件排序 */
    watch(
      () => data.value.checkOptions.length,
      val => viewer.updateSortedWidgets()
    )

    return {
      ...refs,

      widgetBase,

      /** 鼠标悬浮 */
      hovering,

      /** 控件移动 */
      baseDrag,

      /** 激活的索引 */
      activeIndex,

      /** 激活选项 */
      activeOption
    }
  }
})
</script>

<style lang="scss">
.fa-widget-check-group {
  &:hover,
  &.is-activate {
    .add-button {
      display: block;
    }
  }

  .add-button {
    $s: 24px;
    position: absolute;
    top: 100%;
    left: 50%;
    display: none;
    width: $s;
    height: $s;
    margin-top: 8px;
    margin-left: math.div(-$s, 2);
    color: #fff;
    line-height: $s;
    text-align: center;
    cursor: pointer;

    /** hover 占位 */
    &::after {
      position: absolute;
      right: 0;
      bottom: 100%;
      left: 0;
      height: 8px;
      content: '';
    }

    &.is-disabled.el-tooltip {
      background-color: $color-text-disabled;
      cursor: not-allowed;
    }
  }

  .select-box {
    pointer-events: none;
  }

  /** 设置时不鼠标穿透 */
  &.widget-mode-set .select-box {
    pointer-events: all;
  }

  /** 填写时默认隐藏边框，悬浮或聚焦才出现 */
  &.widget-mode-use {
    .select-box {
      display: none;
    }

    &:hover,
    &.is-selecting,
    &.is-activate {
      .select-box {
        display: block;
      }
    }
  }

  &.is-addable {
    &:hover,
    &.is-active {
      .fa-widget-label__wrapper {
        margin-top: 40px;
      }
    }
  }

  // 参与方颜色样式
  @each $c, $color in $actor-colors {
    .actor-#{$c} {
      .fa-widget__box,
      &.is-widget-active .fa-widget__box,
      &.is-widget-active .fa-widget__box:hover,
      & .fa-widget__box:hover {
        background-color: rgba($color, 0.02);
      }

      .add-button {
        background-color: $color;
        border-radius: 2px;
      }
    }
  }
}
</style>
